![API Gateway と Lambdaを使ってサーバレスでいい感じのリダイレクト環境を作る](https://devio2023-media.developers.io/wp-content/uploads/2015/07/api_gateway.png)
API Gateway と Lambdaを使ってサーバレスでいい感じのリダイレクト環境を作る
こんにちは、岩本です。
さて、サイトリニューアルやシステムのリプレイスなどで、サイトのドメインやURL構成が変わる場合、
既存ドメイン・URLへのアクセスを、新環境へリダイレクトするケースが発生するかと思います。
そこで、リダイレクト用だけに維持し続けるのは勿体無いので、API Gateway と Lambda を使って
リダイレクト用の環境を構築して見ました。
やりたいこと
- URL: https://old.hogehoge.com/user?name=xxxxx
に接続が来たら
- URL: https://new.hogehoge.com/user/name/xxxxx
へと、リダイレクトを行いたい。
概要
- APIGatewayで受け取ったURL Query Stringの値をLambdaに引き渡す
- Lambdaでいい感じに変換
- Lambdaで変換された出力を元に、APIGatewayで レスポンスコード(301)の出力と、Locationヘッダーに結果を付与する
Lambdaの用意
まず、URLの変換を行うためのLambdaを用意します。
仕組みは、入力された値をリダイレクト先のURLに付与して、Locationの値として出力します。
def lambda_handler (event, context): name = event['name'] header_location = ("https://new.hogehoge.com/user/name/%s" % name) result = {"Location": header_location} return result
Lambdaのテスト
まずは、Lambdaが期待値通りの動きをすか確認するため、入力値は以下のように設定しテストを行いました。
- 入力
{ "name": "hogehogetarou" }
結果、出力は以下のようになっているので、成功です。
- 出力
{ "Location": "https://new.hogehoge.com/user/name/hogehogetarou" }
APIGatewayの用意
次に、API Gateway にてAPIを作成します。
- リソースを作成
- メソッドを作成
- 今回は、ANYとして作成しました。
- ANYメソッドからLambdaが呼び出されるように設定
- 作成された
ANY
メソッドにて以下を設定
Method Request
Method Request
よりURL Query String Parameters
に name
としてパラメータの追加をします。
追加するパラメータは以下の通りです。
{ "name": "$input.params('name')" }
次に、パラメータを入力後Caching
にチエックをします。
Integration Request
Integration Request
よりBody Mapping Templates
に
application/json
のContent-Type
を追加します。
追加後application/json
の内容を以下の通りとします。
{ "name": "$input.params('name')" }
ここまでが、URLへのアクセスに基づくLambdaへの値の入力設定となります。
Method Response
次にLambdaで生成されたURLをヘッダーに含めるための設定をします。
Method Response
にて、HTTP Status
にリダイレクトのレスポンスコードとなる301
を追加します。
次にResponse Headers for 301
にて、Header
にLocation
を追加します。
integration response
最後に、integration response
にて301
を追加し200
を消します。
追加した301
のHeader Mappings
にMethod Response
にて追加されたLocation
があるので、
値にintegration.response.body.Location
を追加します。
以上で完了です。
TEST
最後にテストをします。
TEST
に進みQuery Strings
にname
という項目があるのでhogetarou
など適当な値を入れテストを実行します。
結果がこちらです。
Request: /?name=hoge Status: 301 Latency: 111 ms Response Body
- Response Body
{ "Location": "https://new.hogehoge.com/user/name/hogetarou" }
- Response Headers
{"X-Amzn-Trace-Id":"Root=1-58ca0c80-b6fe8fb2f9708f96da189497","Content-Type":"application/json","Location":"https://new.hogehoge.com/user/name/hogetarou"}
- リクエストに対し、302のエラーコードが帰っています。
- ヘッダーの
Location
にきちんと生成されたURLが入っています。
ここまでできれば、今作成したResourcesを元にAPIを作成することで、完了です。
解説
入力
Method Request
のURL Query String Parameters
とintegration response
のBody Mapping Templates
に設定した、
"name": "$input.params('name')"
により、URLのQuery Stringの値がLambdaに引き渡されます。
出力
引き渡された値は、integration response
のHeader Mappings
Method Response
に設定した
integration.response.body.xxx
にて、ヘッダーに値が割り当てられます。
今回はLambdaでの出力値Location
つまりintegration.response.body.Location
と設定しました。
今日のわさび様<
お饅頭感がすごい。窓ガラス掃除しないとなぁ。